	//
	//  Album.swift
	//  hello
	//
	//  Created by 赵康 on 2024/11/11.
	//

import Fluent
import Vapor

final class Album: Model, Content, @unchecked Sendable, Logging {
	
	static var schema: String { SchemaEnum.albums.rawValue }
	
	@ID(key: .id)
	var id: UUID?
	
	@Field(key: FieldKeys.title)
	var title: String
	
	@OptionalField(key: FieldKeys.description)
	var description: String?
	
	@OptionalField(key: FieldKeys.cover)
	var cover: String?
	
	@Field(key: FieldKeys.audioCount)
	var audioCount: Int
	
	@Field(key: FieldKeys.playCount)
	var playCount: Int
	
	@Field(key: FieldKeys.favoriteCount)
	var favoriteCount: Int
  
  @Field(key: FieldKeys.wordCount)
  var wordCount: Int
  
	@OptionalField(key: FieldKeys.isDeleted)
	var isDeleted: Bool?
	
	@Timestamp(key: FieldKeys.createdAt, on: .create)
	var createdAt: Date?
	
	@Timestamp(key: FieldKeys.updatedAt, on: .update)
	var updatedAt: Date?
	
	@Children(for: \.$album)
	var audios: [Audio]
	
	@Children(for: \.$album)
	var favorites: [Favorite]
	
	@Enum(key: FieldKeys.category)
	var category: Category
	
	@Siblings(through: AlbumTag.self, from: \.$album, to: \.$tag)
	var tags: [Tag]
	
	var isFavorite: Bool?
	
	init() { }
	
	init(id: UUID? = nil,
			 title: String,
			 description: String?,
			 cover: String?,
			 audioCount: Int = 0,
			 playCount: Int = 0,
			 favoriteCount: Int = 0,
       wordCount: Int = 0,
			 isDeleted: Bool?,
			 createdAt: Date?,
			 updatedAt: Date?,
			 audios: [Audio] = [],
			 favorites: [Favorite] = [],
			 category: Category,
			 tags: [Tag] = [],
			 isFavorite: Bool? = nil) {
		self.id = id
		self.title = title
		self.description = description
		self.cover = cover
		self.audioCount = audioCount
		self.playCount = playCount
		self.favoriteCount = favoriteCount
    self.wordCount = wordCount
		self.isDeleted = isDeleted
		self.createdAt = createdAt
		self.updatedAt = updatedAt
		self.category = category
		self.isFavorite = isFavorite
	}
  
  enum Category: String, Codable, CaseIterable {
    case music
    case talkShow
    case audioBook
    case news
    case movie
    case documentary
    case basicLevel
  }
}
	// 响应模型
struct AlbumResponse: Content, Sendable {
	let id: UUID?
	let title: String
	let description: String?
	let cover: String?
	let audioCount: Int
	let playCount: Int
	let favoriteCount: Int
  let wordCount: Int
	let category: Album.Category  // 使用 Album.Category
	let isFavorite: Bool
	let tags: [TagResponse]
	let createdAt: Date?
	let updatedAt: Date?
	
		// 初始化方法
	init(id: UUID?,
			 title: String,
			 description: String?,
			 cover: String?,
			 audioCount: Int,
			 playCount: Int,
			 favoriteCount: Int,
       wordCount: Int,
			 category: Album.Category,
			 isFavorite: Bool,
			 tags: [TagResponse],
			 createdAt: Date?,
			 updatedAt: Date?) {
		self.id = id
		self.title = title
		self.description = description
		self.cover = cover
		self.audioCount = audioCount
		self.playCount = playCount
		self.favoriteCount = favoriteCount
    self.wordCount = wordCount
		self.category = category
		self.isFavorite = isFavorite
		self.tags = tags
		self.createdAt = createdAt
		self.updatedAt = updatedAt
	}
}

extension Album {
	struct Create: Content {
		var title: String
		var description: String?
		var cover: String?
		var category: Category
		var tagNames: [String]? = []
	}
}

struct PublicAudioItem: Content {
  let id: UUID
  let title: String
  let author: String
  let duration: Double
  let cover: String?
}

// Public album response for sharing endpoint
struct PublicAlbumResponse: Content {
  let id: UUID
  let title: String
  let description: String?
  let cover: String?
  let audioCount: Int
  let playCount: Int
  let category: Album.Category
  let tags: [TagResponse]
  let audios: [PublicAudioItem]
  let shareUrl: String
  
  // 添加自定义编码方法，确保description字段正确序列化
  func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    
    try container.encode(id, forKey: .id)
    try container.encode(title, forKey: .title)
    try container.encode(cover, forKey: .cover)
    try container.encode(audioCount, forKey: .audioCount)
    try container.encode(playCount, forKey: .playCount)
    try container.encode(category, forKey: .category)
    try container.encode(tags, forKey: .tags)
    try container.encode(audios, forKey: .audios)
    try container.encode(shareUrl, forKey: .shareUrl)
    
    // 特殊处理description字段
    if let desc = description {
      try container.encode(desc, forKey: .description)
    } else {
      try container.encodeNil(forKey: .description)
    }
  }
  
  enum CodingKeys: String, CodingKey {
    case id, title, description, cover, audioCount, playCount, category, tags, audios, shareUrl
  }
}

struct ShareLinkResponse: Content {
  let id: UUID
  let title: String
  let shareURL: String
} 